package com.mingqijia.gassafety.webserver.strategy.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.gap.basic.exception.BizException;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.db.entity.WarnStrategy;
import com.mingqijia.gassafety.db.entity.WarnStrategyExt;
import com.mingqijia.gassafety.db.mapper.ContactsMapper;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.MessagePushTypeEnum;
import com.mingqijia.gassafety.shared.constant.PushTypeEnum;
import com.mingqijia.gassafety.shared.constant.warnStrategy.WarnStrategyIntervalEnum;
import com.mingqijia.gassafety.shared.constant.warnStrategy.WarnStrategyTypeEnum;
import com.mingqijia.gassafety.shared.dto.AssembleTemplateDTO;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.webserver.dto.PredateStrategyDTO;
import com.mingqijia.gassafety.webserver.dto.SendMessageDTO;
import com.mingqijia.gassafety.webserver.service.impl.CompanyServiceImpl;
import com.mingqijia.gassafety.webserver.service.strategy.WarnStrategyV2ServiceImpl;
import com.mingqijia.gassafety.webserver.strategy.PredicateGasWarnStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务到期当天 策略实现
 * </p>
 *
 * @author mby
 * @since 2024-01-16
 */
@Service
@Slf4j
public class PredicateGasHighWarnStrategy implements PredicateGasWarnStrategy { // 实现策略

    @Autowired
    RedisCache redisCache;

    @Autowired
    ContactsMapper contactsMapper;

    @Autowired
    CompanyServiceImpl companyService;

    @Resource
    WarnStrategyV2ServiceImpl warnStrategyV2Service;

    @Autowired
    SendMessageService sendMessageService;

    /**
     * 信息发送判定，组装数据
     * @param dtuMap 报警策略所需数据
     * @param warnStrategyExtList 策略明细列表
     * @param cacheMap 缓存
     * @param sendDataList  组装的发送数据列表
     * @param predateStrategyDTO 信息发送判断，组装数据策略所需的数据
     */
    @Override
    public void predicateGasWarn(Map<String, Object> dtuMap, List<WarnStrategyExt> warnStrategyExtList, Map<String, Object> cacheMap,
                                 List<SendMessageDTO> sendDataList, PredateStrategyDTO predateStrategyDTO) {
        // 判断是不是高报
        if (!checkHighReport(dtuMap.get("high_report") + "", predateStrategyDTO.getValue())) {
            // 不是高报，返回
            return;
        }
        log.info("warnStrategyV2-predicateGasHighWarn-高报:{}", predateStrategyDTO.getImei());
        // 判断是不是首次触发
        if (cacheMap != null && cacheMap.size() > 0) {
            log.info("warnStrategyV2-predicateGasHighWarn-非首次触发:{}", predateStrategyDTO.getImei());
            return;  // 这里只接受首次触发
        }

        String smsMsgCode = StringUtils.isEmpty(dtuMap.get("high_sms_msg_code"))?Constants.STR_EMPTY:dtuMap.get("high_sms_msg_code").toString();
        String wxMsgCode = StringUtils.isEmpty(dtuMap.get("high_wx_msg_code"))?Constants.STR_EMPTY:dtuMap.get("high_wx_msg_code").toString();
        dtuMap.put("sms_msg_code",smsMsgCode);
        dtuMap.put("wx_msg_code",wxMsgCode);

        // 首次触发报警需要组装一些基础信息
        cacheMap.put("iMEI", predateStrategyDTO.getImei());
        cacheMap.put("spId", predateStrategyDTO.getSpId());
        cacheMap.put("count", 1);
        cacheMap.put("path", dtuMap.get("Path"));
        cacheMap.put("strategyId", dtuMap.get("strategyId"));
        cacheMap.put("consumerId", dtuMap.get("consumer_id"));
        cacheMap.put("identificationCode", predateStrategyDTO.getSnowflakeId());
        cacheMap.put("smsMsgCode",smsMsgCode);
        cacheMap.put("wxMsgCode",wxMsgCode);

        cacheMap.put("type", WarnStrategyTypeEnum.HIGH.getCode()); //高报
        dtuMap.put("type", WarnStrategyTypeEnum.HIGH.getCode()); //高报

        // 开启了本地消息发送
        try {
            if (PushTypeEnum.getPushTypes(null, MessagePushTypeEnum.LOCAL.getGasWarnCode()).contains(Integer.parseInt(dtuMap.get("high_type").toString()))) {
                // 判断是否发送本地消息，如果是，组装发送信息
                warnStrategyV2Service.predicateSendLocal(WarnStrategyTypeEnum.HIGH, dtuMap, cacheMap, sendDataList, predateStrategyDTO);
            }
        } catch (Exception e) {
            log.error("warnStrategyV2-predicateGasHighWarn-local-error:{}", e);
        }

        // 开启了短信消息发送
        try {
            if (PushTypeEnum.getPushTypes(null, MessagePushTypeEnum.SMS.getGasWarnCode()).contains(Integer.parseInt(dtuMap.get("high_type").toString()))) {
                // 判断是否发送短信消息，如果是，组装发送信息
                warnStrategyV2Service.predicateSendSms(WarnStrategyTypeEnum.HIGH, dtuMap, warnStrategyExtList, cacheMap, sendDataList, predateStrategyDTO);
            }
        } catch (Exception e) {
            log.error("warnStrategyV2-predicateGasHighWarn-sms-error:{}", e);
        }

        // 开启了微信模板消息发送
        try {
            if (PushTypeEnum.getPushTypes(null, MessagePushTypeEnum.WX.getGasWarnCode()).contains(Integer.parseInt(dtuMap.get("high_type").toString()))) {
                // 判断是否发送微信消息，如果是，组装发送信息
                warnStrategyV2Service.predicateSendWx(WarnStrategyTypeEnum.HIGH, dtuMap, cacheMap, sendDataList, predateStrategyDTO);
            }
        } catch (Exception e) {
            log.error("warnStrategyV2-predicateGasHighWarn-wx-error:{}", e);
        }

        // 开启了机器人外呼发送
        try {
            if (PushTypeEnum.getPushTypes(null, MessagePushTypeEnum.CALL.getGasWarnCode()).contains(Integer.parseInt(dtuMap.get("high_type").toString()))) {
                // 判断是否发送机器人外呼，如果是，组装发送信息
                warnStrategyV2Service.predicateSendCall(WarnStrategyTypeEnum.HIGH, dtuMap, warnStrategyExtList, cacheMap, sendDataList, predateStrategyDTO);
            }
        } catch (Exception e) {
            log.error("warnStrategyV2-predicateGasHighWarn-call-error:{}", e);
        }
    }


    /**
     * 校验是否高报
     * @param highReport 配置的高报值
     * @param value 当前浓度值
     */
    public boolean checkHighReport(String highReport, Integer value) {
        if (!StringUtils.isEmpty(highReport) && NumberUtil.isNumber(highReport)) {
            if (value >= Integer.parseInt(highReport)) {
                return true;
            }
        }
        return false;
    }

}
